package crawler;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.parserapplications.StringExtractor;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.ObjectFindingVisitor;

import structures.InfoPacket;
import structures.TaskType;

public class Crawler extends Thread {

	// połączenie z serwerem
	CrawlerConnection connection;

	// konstruktor z połączeniem
	public Crawler(int port, String address) {
		connection = CrawlerConnection.getConnector(port, address);
	}

	//wyszukiwanie słowa na stronie
	private boolean findWord(String currentURL,String phrase) {
		StringExtractor extractor = new StringExtractor(currentURL);
		boolean returnValue = false;
		try {
			String a = extractor.extractStrings(false);
			returnValue = a.contains(phrase);
		} catch (ParserException e) {
			e.printStackTrace();
		}

		return returnValue;
	}

	//wyszukiwanie linków na stronie
	private List<String> parseURL(String currentURL) {

		/*System.out.println("Crawler - przeszukuje strony dla linków: " + currentURL);*/
		Parser parser = null;
		List<String> returnList=new LinkedList<String>();
		try {
			parser = new Parser(currentURL);
		} catch (ParserException e) {
			return returnList;
		}

		ObjectFindingVisitor visitor = new ObjectFindingVisitor(LinkTag.class);

		try {
			parser.visitAllNodesWith(visitor);
		} catch (ParserException e) {
			e.printStackTrace();
		}

		Node[] links = visitor.getTags();
		for (int i = 0; i < links.length; i++) {
			LinkTag linkTag = (LinkTag) links[i];
			returnList.add(linkTag.getLink());
			/*System.out.println("Crawler - znalazłem link:"
					+ linkTag.getLink());*/

		}
		return returnList;

	}

	public void run() {
		while (true) {
			InfoPacket packet = null;
			try {
				packet = connection.receivePacket();
			} catch (IOException e) {
				System.out.println("Crawler: Could not receive a packet with a task");
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			
			//dla każdej strony wyszukuje linki
			InfoPacket retPacket=new InfoPacket(packet.getPage());
			retPacket.setUrlList(parseURL(packet.getPage()));

			if(packet._taskList.contains(TaskType.shutdown))
				System.out.println("Po stronie serwera ok;");
			
			
			
			//sprawdza, czy serqwer zakończył działanie. jesli tak, kończy działanie.
			if(packet.getTaskList().contains(TaskType.shutdown))
			{
				System.out.println("Kończenie pracy Crawlera");
				connection.shutDown();
				return;
				
			}
			

			//dodatkowo sprawdza jakie ma zdania i wywołuje odpowiednie funkcje
			for(TaskType t:packet.getTaskList()){
				if(t==TaskType.keyword){
					Boolean retBool=new Boolean(findWord(packet.getPage(),(String)packet.getTaskArgument(t)));
					retPacket.addTask(t,retBool);
					
				}
			}
			try {
				connection.sendInfoPacket(retPacket);
			} catch (IOException e) {
				System.out.println("Nie można nawiązać połączenia z serwerem, kończę działanie.");
				return;
			}

		}
	}
}
